<script setup lang="ts">
// import MyBtnDemo from 'vue3-ai'


import Seed from "~/components/ai/Seed.vue";
import Negative from "~/components/ai/Negative.vue";
import Positive from "~/components/ai/Positive.vue";
import Denoise from "~/components/ai/Denoise.vue";
import ModelSelect from "~/components/ai/ModelSelect.vue";
import Width from "~/components/ai/Width.vue";
import Height from "~/components/ai/Height.vue";
import GalleriaViewBase from "~/components/ai/GalleriaViewBase.vue";
import {
  ComfyUI,
  type ComfyUIProperties,
  type DrawHistoryItem, type DrawResponse,
  type OutPut,
  type OutputType, type Param,
} from "~/utils/comfyuiApi";
import {type Image, socketInit} from "~/composables/drawhooks";
import ImageUploadAuto from "~/components/ai/ImageUploadAuto.vue";
import VideoPlayer from "~/components/video/VideoPlayer.vue";
import CustomNumberInput from "~/components/ai/CustomNumberInput.vue";
import CustomTextInput from "~/components/ai/CustomTextInput.vue";
import ProgressBarBase from "~/components/common/ProgressBarBase.vue";
import CustomDropSelect from "~/components/ai/CustomDropSelect.vue";
import KonvaEditor from "~/components/knova/KonvaEditor.vue"; //自定义数字输入


const {workflow_name, user_id: workflow_user_id} = useRoute().params
const {user, isLoginedIn} = storeToRefs(useAuthStore())
const {operationConfig: {enableMultiTask}} = useAppStore()
const {isGernateDisable} = storeToRefs(useStableDiffusionStore())


onMounted(async () => {
  socketInit()
  await Promise.all([ComfyUI.Initalize(), getWorkFlow()])
})

//进度

const commonents = {
  Seed,
  Negative,
  Positive,
  Denoise,
  ModelSelect,
  Width,
  Height,
  ImageUploadAuto,
  CustomNumberInput,
  CustomTextInput,
  CustomDropSelect
}

//参数与组件的对应关系

interface ParamToComponent {
  param: keyof ComfyUIProperties,
  component: keyof typeof commonents
  title?: string
}

//参数与组件的对应关系
const params_component = [
  {param: 'seed', component: 'Seed', title: '随机种子'},
  {param: 'negative', component: 'Negative', title: '反向提示词'},
  {param: 'positive', component: 'Positive', title: '正向提示词'},
  {param: 'denoise', component: 'Denoise', title: '重绘幅度'},
  {param: 'ckpt_name', component: 'ModelSelect', title: '模型选择'},
  {param: 'width', component: 'Width', title: '图片宽度'},
  {param: 'height', component: 'Height', title: '图片高度'},
  {param: 'image_path_origin', component: 'ImageUploadAuto', title: '原图上传'},
  {param: 'image_path_mask', component: 'ImageUploadAuto', title: '遮罩上传'},
  {param: 'image_path_face', component: 'ImageUploadAuto', title: '脸部参考上传'},
  {param: 'image_path_style', component: 'ImageUploadAuto', title: '风格参考上传'},
  {param: 'custom_dropselect_1', component: 'CustomDropSelect', title: '自定义下拉列表'},
  {param: 'custom_dropselect_2', component: 'CustomDropSelect', title: '自定义下拉列表'},
  {param: 'custom_number_1', component: 'CustomNumberInput', title: '自定义数字'},
  {param: 'custom_string_1', component: 'CustomTextInput', title: '自定义文本'},
  {param: 'custom_number_2', component: 'CustomNumberInput', title: '自定义数字'},
  {param: 'custom_string_2', component: 'CustomTextInput', title: '自定义文本'},
  {param: 'custom_number_3', component: 'CustomNumberInput', title: '自定义数字'},
  {param: 'custom_string_3', component: 'CustomTextInput', title: '自定义文本'},
  {param: 'custom_number_4', component: 'CustomNumberInput', title: '自定义数字'},
  {param: 'custom_string_4', component: 'CustomTextInput', title: '自定义文本'},
  {param: 'custom_number_5', component: 'CustomNumberInput', title: '自定义数字'},
  {param: 'custom_string_5', component: 'CustomTextInput', title: '自定义文本'},
  {param: 'custom_number_6', component: 'CustomNumberInput', title: '自定义数字'},
  {param: 'custom_string_6', component: 'CustomTextInput', title: '自定义文本'},
] as ParamToComponent[]



const output_type = ref<OutputType>('image')
//组件与参数的绑定关系，倒过来
//绑定参数
const bind_params = ref<ComfyUIProperties>({
  negative: "",
  positive: "",
  denoise: 0.5,
  ckpt_name: '',
  width: 1024,
  height: 1024,
  image_path_origin: '',
  image_path_mask: '',
  image_path_face: '',
  image_path_style: '',
  advance_onlineEdit_origin:'',
  advance_onlineEdit_mask:''
})


watch(bind_params, (new_value) => {
  console.log('绑定参数', new_value)
}, {
  deep: true
})

interface DynamicComponent {
  paramName: string,
  component: string
}

//动态组件列表
const dynamicComponentList = ref<DynamicComponent[]>([])
// dynamicComponentList.value.push("Seed", "Negative", "Positive", "Denoise", "ModelSelect", "Width", "Height")

definePageMeta({
  //布局
  layout: 'ui-layout',
  validate: async (route: any) => {
    return true
  }
})


const prompt = ref<any>()
const params = ref<any[]>([])
const workflow_app = ref<any>()

/**
 * 判断params中是否含有advance_onlineEdit_mask的属性
 */
const isAdvanceOnlineEditMask = computed(() => {
  for (const item of params.value) {
    if (item.name === 'advance_onlineEdit_mask') {
      return true
    }
  }
  return false
})

/**
 * 获取工作流
 */
//获取工作流
const getWorkFlow = async () => {
  if (workflow_user_id && workflow_name) {
    const workflow = await ComfyUI.getSharedWorkFlow(workflow_user_id as string, workflow_name as string)
    if (!workflow) {
      return
    }
    // 获取工作流的节点数和预runTime，第一次没有数据使用默认数据
    console.log(`获取的工作流总步数${workflow.nodeCount}预计运行时间${workflow.runTime}`)
    // 获取工作流的参数
    workflow_app.value = workflow
    prompt.value = JSON.parse(workflow.workflow || '{}')
    params.value = formatParams(workflow.params!)
    console.log("workflow", prompt.value, params.value)
    if (!params.value) {
      return
    }
    for (const _param of workflow.params) {
      //将默认参数赋值给绑定参数
      bind_params.value[_param.name] = _param.param
      //用户自定义的名字赋值给params_component的title属性
      if (_param.title && _param.name !== 'output' && !_param.name.includes('advance')) {
        params_component[params_component.findIndex(item => item.param === _param.name)].title = _param.title
      }
      console.log("_param.name", _param)
      if (_param.name === 'output') {
        output_type.value = _param.outputType as OutputType
      }
      //根据节点名称，找到对应的组件
      const index = params_component.findIndex(item => item.param === _param.name)
      if (index != -1) {
        dynamicComponentList.value.push({
          paramName: _param.name,
          component: params_component[index].component
        })
      }
    }
  }
}


/**
 * 格式胡param参数，将传递的参数转换为组件需要的格式，格式化json
 */
const formatParams = (params:Param[]) => {
  //格式化attribute
  let newParams=[] as Param[]
  for (const item of params) {
      if(item.attributes){
        item.attributes=JSON.parse(item.attributes+'')
      }
      newParams.push(item)
  }
  return newParams
}


const outputs = ref<OutPut[]>([])
/**
 * 提交生成图片
 */
const submit = async () => {
  //验证登录
  if (!isLoginedIn.value || !user.value || !user.value._id) {
    useSnackbarStore().showWarningMessage('请先登录！')
    return
  }
  isGernateDisable.value = true
  await handleUploadMask()
  //验证图片上传是否完成，也就是image的参数是否为空
  for (const item of params.value) {
    if (item.name === 'image_path_origin' || item.name === 'image_path_mask' || item.name === 'image_path_face' || item.name === 'image_path_style') {
      if (!bind_params.value[item.name]) {
        useSnackbarStore().showWarningMessage('上传图片地址不能为为空，请等待图片上传完成！')
        return
      }
    }
  }
  //随机种子
  bind_params.value['seed'] = ComfyUI.getSeed()
  //显示进度条
  //提交绘画
  console.log(prompt.value)
  const result = await ComfyUI.runSharedWorkFlow(prompt.value, params.value, bind_params.value, {
    workflow_user_id: workflow_user_id! as string,
    workflow_name: workflow_name as string,
    servername:ComfyUI.preAssignedServer?.name || ''
  }) as DrawResponse
  console.log('绘画结果', result)
  if (result && result.status === 'success' && result?.output?.length && result?.output.length > 0) {
    for (const _url of result.output) {
      const output = {result: _url, params: bind_params.value, type: output_type.value} as OutPut
      console.log('最终绘图产出', output)
      outputs.value.unshift(output)
      useAuthupdateUserInfo().then()  //不需要await
    }

    //保存绘画历史记录,不需要await
    ComfyUI.saveDrawHistory({
      params: bind_params.value,
      options: {
        workflow_user_id: workflow_user_id! as string,
        workflow_name: workflow_name as string
      },
      output: result.output,
      type: output_type.value || result.type || 'image'
    } as DrawHistoryItem).then()

  } else {
    if (result) {
      useSnackbarStore().showWarningMessage(result.message || '绘画失败')
    }
  }
  isGernateDisable.value = false
}

//获取工作流的任务cosnt

const konvaEditor=ref()
const handleUploadMask=async () => {
  console.log(params.value)
  const promises=[]
  if(params.value.findIndex(item=>item.name==='advance_onlineEdit_mask')!==-1){
    promises.push(konvaEditor.value.handleUploadMaskLayer())
  }
  if(params.value.findIndex(item=>item.name==='advance_onlineEdit_origin')!==-1){
    promises.push(konvaEditor.value.handleUploadBaseLayer())
  }
  const results=await Promise.all(promises)
  bind_params.value.advance_onlineEdit_mask=results[0]
  bind_params.value.advance_onlineEdit_origin=results[1]
}

</script>

<template>
  <v-container>
    <v-row>
      <v-col cols="12" md="4">
        <v-card>
          <v-card-text>
            <KonvaEditor v-if="isAdvanceOnlineEditMask" ref="konvaEditor" />
            <component v-for="dynamicComponent in dynamicComponentList"
                       :title="params_component[params_component.findIndex(item => item.param === dynamicComponent.paramName)].title"
                       :is="commonents[params_component[params_component.findIndex(item => item.param === dynamicComponent.paramName)].component]"
                       v-model="bind_params[params_component[params_component.findIndex(item => item.param === dynamicComponent.paramName)].param]"
                       :options="params.find(item=>item.name===dynamicComponent.paramName).attributes"></component>
          </v-card-text>
          <v-card-actions>
            <v-btn @click="submit" variant="flat" color="primary" block
                   :loading="enableMultiTask?false:isGernateDisable">
              生成
            </v-btn>
          </v-card-actions>
        </v-card>
      </v-col>
      <v-col cols="12" md="8">
        <v-card min-height="600">

          <v-sheet class="d-flex flex-column align-center justify-center">
            <!--            进度条-->
            <progress-bar-base v-if="isGernateDisable"/>
            <!--            <progress-bar-base/>-->
            <!--          无数据页面-->
            <v-card-text v-if="outputs.length===0">
              <v-sheet height="600" class="d-flex flex-column align-center justify-center">
                <v-icon size="100" color="primary">mdi-image-filter-hdr</v-icon>
                <h1 class="text-h6 font-weight-bold text-center">暂无数据，生成结果将会显示在这里</h1>
                <v-label>点击按钮，使用随机提示词</v-label>
                <v-btn class="mt-6" color="primary" @click="submit">
                  使用随机提示词
                </v-btn>
              </v-sheet>

            </v-card-text>
            <!--          有数据页面-->
            <v-card-text v-else class="d-flex flex-column align-center justify-center">
              <!--          图片预览-->
              <GalleriaViewBase v-if="output_type==='image'||!output_type" v-model="outputs" src-label="result"
                                thumbnail-label="result"
                                alt-label="params"/>
              <v-sheet v-else-if="output_type==='video'&&outputs[0].result">
                <v-label class="mb-4 mt-4 font-weight-bold">生成视频：</v-label>
                <video-player :width="600" :height="600" :src="outputs[0].result"></video-player>
              </v-sheet>
              <!--            产出是文本-->
              <v-sheet v-else-if="output_type==='text'">
                <v-label class="mb-4 mt-4 font-weight-bold">反推提示词：</v-label>
                <v-textarea width="450" variant="outlined" v-model="outputs[0].result"></v-textarea>
              </v-sheet>
            </v-card-text>

          </v-sheet>
        </v-card>
      </v-col>
    </v-row>


    <!--<seed/>-->
    <!--  <negative> </negative>-->
    <!--  <positive/>-->
    <!--  <denoise/>-->
    <!--  <model-select/>-->
    <!--  <width/>-->
    <!--  <height/>-->
    <!--  <image-upload/>-->
    <!--  <image-upload-auto/>-->
    <!--    <custom-number-input/>-->
    <!--    <custom-text-input/>-->
<!--    <CustomDropSelect />-->
  </v-container>
</template>

<style scoped lang="scss">

</style>